package com.woniuxy.lab.woniu_lab_boss.Security;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniuxy.lab.woniu_lab_boss.Security.comment.LoginErrorHandler;
import com.woniuxy.lab.woniu_lab_boss.Security.comment.LoginSuccessHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author chenweiji
 */
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Slf4j
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    private LoginSuccessHandler loginSuccessHandler;

    @Resource
    private LoginErrorHandler loginErrorHandler;
    @Resource
    private ObjectMapper objectMapper;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //禁用httpBasic验证
        http.httpBasic().disable()
                //关闭浏览器内部窗口的安全参数
                .headers().frameOptions().disable()
                //关闭csrf的拦截
                .and().csrf().disable()
                //开始配置请求认证
                .authorizeRequests()
                //拦截器白名单（放过的）
                .antMatchers("/account/login","/page/login.html", "/js/**", "/css/**","/**","/swagger-ui.html","/login").permitAll()
                //其他的全拦截
                .anyRequest().authenticated()
                .and()
                //表单登录
                .formLogin()
                //登录页面
                .loginPage("/page/login.html")
                //登录接口
//                .loginProcessingUrl("/account/login")
                //成功处理
                .successHandler(loginSuccessHandler)
                //失败处理
                .failureHandler(loginErrorHandler)
                //优化无权限异常
                .and().exceptionHandling().accessDeniedHandler(accessDeniedHandler());
    }

    @Bean
    public AccessDeniedHandler accessDeniedHandler() {
        return new AccessDeniedHandler() {
            @Override
            public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
                SecurityUtil.requestResult(httpServletResponse, "您无权访问", 403);
            }
        };
    }

    /**
     * 登录接口要用，具体啥用我也不知道
     * @return AuthenticationManager
     * @throws Exception
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    /**
     * 加密器
     * @return
     */
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}
